#ifndef TESTS_H
#define TESTS_H

/**
* \class Tests
* \brief This class is used to generate the test reports for a regression testing. It will do similar operation as the class program
* \author Elie M. Shaccour (elie.shaccour@gmail.com)
* 
*/

class Projects;
class Program;
class AntlrAdapter;

class Tests {

enum State{
	ChooseProject,
	GenerateTest,
	Invalid
	};

private:
///Keeps track in which state we are currently
	State CurrentState;
///Programs available for the user to test
	Projects *MyProjects;
/// Vector containing all the TestCriterion previously set by the user
	std::vector<std::string> TestCriteria;
/// Vector hold 1-to-1 mapping with the TC vector i.e. Testfile.at(0) is for TC.at(0)
	std::vector<std::string> TestFile;
/// Boolean to know if this is a test in GUI mode
	bool IsGUI;
///Number of programs available to the user
	int max;
/// String holding the data to be printed on the screen
	std::string Print;
///Number of the program currently working on
	int CurrentProgramPosition;

	/**     \brief This is the main test function. It will take a testfile and criteria and find their assembly positions in the new program 
        *       \param Test_Criteria Test criteria set for this program
	*	\param Test_File Testfile set to exercise the previous criterion
        *       \return The requirements line for this specific criteria and testfile
        */
	std::string GetRequirements(std::string Test_Criteria, std::string Test_File);

	/**     \brief This is the main test function. It will take a testfile and criteria and find their assembly positions in the new program 
        *       \param Test_Criteria Test criteria set for this program
        *       \param Test_File Testfile set to exercise the previous criterion
        *       \return The requirements line for this specific criteria and testfile
        */
        std::string GetDefUseRequirements(std::string Test_Criteria, std::string Test_File);

///Object of the program, holds functions and other manipulations on them
	Program *CurrentProgram;
///Object to the ANTLR interface
	AntlrAdapter *C_LR;
///Vector to contain the line number that have assembly address data in the file
	std::vector<int> LineNumbers;
///Vector with 1-to-1 mapping to contain assembly line address for the loc ie. asm_address.at(0) represents the assembly address for source code line loc.at(0)
	std::vector<std::string> AssemblyAddresses;

	/**     \brief Get the assembly line address for the specific line number 
        *       \param LinePosition line number whose assembly address is needed
        *       \return assembly address of the line
        */
	std::string GetAssemblyAddressForLineAtPosition(int LinePosition);

	/**     \brief This function will create the vectors that are needed to get the mapping between source code line number and assembly addresses
        */
	void SetLineNumbersToAssemblyAddressesMapping();
///To know if I should delete program in destructor
	bool DeleteProgram;

	std::string ProjectDirectoryPath;

public:
        /**     \brief Constructor
        *       \param Is_GUI boolean that designates whether this is used in GUI or CMD mode
        */
//	Tests(bool Is_GUI);

	/**	\brief Constructor for public non-DB tool
	*	\param Is_GUI boolean that designates whether this is used in GUI or CMD mode
	*	\param TestCriteria the Test Criteria list previously added
	*	\param TestFiles the test files to exercise the previous test criteria
	*/
	Tests(bool Is_GUI, std::vector<std::string> Test_Criteria, std::vector<std::string> Test_Files,std::string ProjectPath);

	/**     \brief Deletes the temporary files created for the test generation 
        */
	~Tests();

        /**     \brief Goes forward carying all the information that will advance the current state as displayed by the screen menu shown to the user 
        *       \param UserInput Choice from the menu, if needed, to help advance the state of the test of the program
        */
	void GoForward(std::string UserInput);

        /**     \brief Goes a step backward in the screen 
        */
	void GoBackward();

        /**     \brief Returns data that need to be printed on the screen to be shown to the user
        *       \return String containing the information that should currently be displayed on the screen 
        */
	std::string GetPrint();

        /**     \brief Returns the state of the program 
        *       \return int==1 if valid else 0
        */
	int IsValid();
};

#endif
